<html>
<head><meta charset="utf-8"><title>borrow error · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html">borrow error</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="224601290"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224601290" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Eric Huss <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224601290">(Jan 30 2021 at 19:35)</a>:</h4>
<p>It's pretty rare that I have issues with the borrow checker, but when I do it can get really frustrating.  I have this example: <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=143802c4fcf4b43bb4d5676f660e6dde">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=143802c4fcf4b43bb4d5676f660e6dde</a></p>
<p>The commented code works, but if I move the commented code to a function, the borrow checker complains.  No amount of rearranging things or adding lifetime annotations seems to help.  I feel like I'm missing something simple, can anyone spot it?</p>



<a name="224601498"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224601498" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mark Drobnak <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224601498">(Jan 30 2021 at 19:40)</a>:</h4>
<p>Changing</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="n">v</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="nb">None</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">v</span><span class="p">,</span><span class="w"></span>
</code></pre></div>
<p>to</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="nb">None</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="o">&amp;</span><span class="nb">None</span><span class="p">,</span><span class="w"></span>
</code></pre></div>
<p>works.</p>



<a name="224601890"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224601890" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224601890">(Jan 30 2021 at 19:51)</a>:</h4>
<p>hmm, it looks like what happened is that <code>map</code> is implicitly reborrowed in the call to f</p>



<a name="224601892"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224601892" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224601892">(Jan 30 2021 at 19:51)</a>:</h4>
<p>I wonder why that happens</p>



<a name="224602042"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602042" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Eric Huss <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602042">(Jan 30 2021 at 19:54)</a>:</h4>
<p>Unfortunately I don't think I can make that change in the real code.  The real code involves a bunch of enum variants with values that should be borrowed (not copied).</p>



<a name="224602044"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602044" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Eric Huss <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602044">(Jan 30 2021 at 19:54)</a>:</h4>
<p>I just used option in the example to simplify it.</p>



<a name="224602233"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602233" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602233">(Jan 30 2021 at 19:59)</a>:</h4>
<p>ok I think I see why it's reborrowed: otherwise it can't be borrowed the second time because &amp;mut T is not Copy</p>



<a name="224602318"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602318" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602318">(Jan 30 2021 at 20:00)</a>:</h4>
<p>this is fixed with -Z polonius btw</p>



<a name="224602444"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602444" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602444">(Jan 30 2021 at 20:03)</a>:</h4>
<p>I don't know if there's a way around this otherwise</p>



<a name="224602519"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602519" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Eric Huss <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602519">(Jan 30 2021 at 20:05)</a>:</h4>
<p>oh, that's interesting!  Thanks for taking a look <span class="user-mention" data-user-id="232545">@Joshua Nelson</span> !  I'm not too familiar with polonius, I'll need to learn more.</p>
<p>Here's a slightly closer example that uses an enum: <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=6d4b16a49a993f973d0781e6487a66b0">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=6d4b16a49a993f973d0781e6487a66b0</a></p>



<a name="224602538"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602538" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602538">(Jan 30 2021 at 20:05)</a>:</h4>
<p>polonius is still a ways off, IIRC cargo wants to build on stable so it's probably not workable in the short-term</p>



<a name="224602580"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602580" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Eric Huss <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602580">(Jan 30 2021 at 20:06)</a>:</h4>
<p>yea.  This isn't for cargo, but I do prefer to stick with stable anyways.</p>



<a name="224602791"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602791" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602791">(Jan 30 2021 at 20:11)</a>:</h4>
<p>This code is safe, but requires position-dependent borrows (or whatever that's called); the first borrow <code>f(map, x)</code> in <code>g</code> ends in one branch but extends out of the function in the other branch.</p>



<a name="224602856"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602856" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602856">(Jan 30 2021 at 20:12)</a>:</h4>
<p>This was apparently a feature that was removed from NLL before it made it into rust 2018, and is in polonius</p>



<a name="224602878"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602878" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Eric Huss <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602878">(Jan 30 2021 at 20:13)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> Do you happen to know if there are any workarounds (even if they are ugly)?</p>



<a name="224602884"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602884" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602884">(Jan 30 2021 at 20:13)</a>:</h4>
<p>If I were in your position I would just transmute my way around the problem</p>



<a name="224602890"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602890" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Eric Huss <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602890">(Jan 30 2021 at 20:13)</a>:</h4>
<p><span aria-label="laughter tears" class="emoji emoji-1f602" role="img" title="laughter tears">:laughter_tears:</span></p>



<a name="224602906"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602906" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602906">(Jan 30 2021 at 20:13)</a>:</h4>
<p>in this case, a <code>mem::transmute::&lt;&amp;Option&lt;String&gt;, &amp;Option&lt;String&gt;&gt;(v)</code> in the none branch should fix it</p>



<a name="224602969"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602969" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602969">(Jan 30 2021 at 20:15)</a>:</h4>
<p>you may want to add a test that it builds with -Z polonius without the transmute lol</p>



<a name="224602973"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224602973" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224602973">(Jan 30 2021 at 20:15)</a>:</h4>
<p>just in case someone changes it later</p>



<a name="224603835"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224603835" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mark Drobnak <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224603835">(Jan 30 2021 at 20:36)</a>:</h4>
<p>Would you be able to move the map into <code>g</code>? That would help.</p>



<a name="224604004"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224604004" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Eric Huss <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224604004">(Jan 30 2021 at 20:40)</a>:</h4>
<p>I don't think so.  The actual code is a file cache.  The function is something like <code>get_entry_from_cache(&amp;mut Cache, &amp;Path)</code>.  Just fetching an entry from a HashMap is simple.  The problem is that the function also needs to check if the entry is a specific kind (a "redirect"), and if it is, follow the redirect to the entry it points to.  That "if entry is redirect then return get_entry_from_cache(cache, target)" is what is tripping things up. </p>
<p>Another option is to just duplicate the logic for that "if is a redirect" in a few places.  I think it's only about 3 lines of code, used only 2 or 3 times.</p>



<a name="224604013"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224604013" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224604013">(Jan 30 2021 at 20:40)</a>:</h4>
<p>you could make it a macro maybe</p>



<a name="224604028"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224604028" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Eric Huss <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224604028">(Jan 30 2021 at 20:41)</a>:</h4>
<p>yea, that would probably help.</p>
<p>I was just hoping I was missing some lifetime annotation that would magically make it work.</p>



<a name="224604091"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224604091" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224604091">(Jan 30 2021 at 20:43)</a>:</h4>
<p>nah, this is just a bug in the borrow checker IMO</p>



<a name="224705468"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/borrow%20error/near/224705468" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/borrow.20error.html#224705468">(Feb 01 2021 at 10:03)</a>:</h4>
<p>Yeah, this is the textbook case of Polonius. The real interesting thing is that when the logic is inlined, the borrow-checker is less strict. That is, the current borrow checker is a bit too strict in its way of special-casing <em>return</em> values.<br>
So your three main choices would be:</p>
<ul>
<li>use a macro indeed, especially given that macros can be re-exported from a module;</li>
<li>use <code>unsafe</code>, since it is a text-book case of a polonius-saved solution (if you want to go crazy, you can <code>cfg</code>-gate the usage of <code>unsafe</code> and transmute, and have / generate some test that runs <code>cargo check</code> with polonius (and its cfg) enabled.</li>
<li>Use continuation-passing style (<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=1080f1ccecb25c62f1b7c8b1c8be3f6e">Demo</a>), which can be made (more) ergonomic using <a href="https://docs.rs/with_locals">https://docs.rs/with_locals</a> (but in this instance it feels inferior to directly using a macro).</li>
</ul>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>